package com.lc.ei.utils;

import com.lc.ei.config.dynamiccomp.ClassFileManager;
import com.lc.ei.config.dynamiccomp.JavaSourceFromString;
import lombok.extern.slf4j.Slf4j;

import javax.tools.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @description: 动态实体类生成工具
 * @author: LChuang
 * @date: 2023/9/19 9:23
 */
@Slf4j
public class GenEntityUtil {

    private static volatile AtomicInteger times = new AtomicInteger(0);

    /**
     * 内存级动态编译，生成实体对象
     *
     * @param fieldList 字段列表
     */
    public static Object memoryGenEntity(List<String> fieldList, String className) {
        // 创建类的源码字符串
        StringBuilder classSource = new StringBuilder();
        // 给实体类加入lombok注解包
        classSource.append("import lombok.AllArgsConstructor;\n" +
                "import lombok.Data;\n" +
                "import lombok.NoArgsConstructor;\n");
        classSource.append("@Data\n" +
                "@AllArgsConstructor\n" +
                "@NoArgsConstructor\n");
        classSource.append("public class ").append(className).append(" {\n");
        for (String fieldName : fieldList) {
            classSource.append("    private String ").append(fieldName).append(";\n");
        }
        classSource.append("}");
        try {
            // 生成源代码的JavaFileObject
            SimpleJavaFileObject fileObject = new JavaSourceFromString(className, classSource.toString());
            JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
            //被修改后的JavaFileManager
            JavaFileManager fileManager = new ClassFileManager(compiler.getStandardFileManager(null, null, null));
            //执行编译
            JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, null, null, Collections.singletonList(fileObject));
            task.call();
            //获得ClassLoader，加载class文件
            ClassLoader classLoader = fileManager.getClassLoader(null);
            Class<?> loadClass = classLoader.loadClass(className);
            // 获得实例对象
            return loadClass.newInstance();
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
            log.error("【内存级动态编译】实例对象创建异常：{}", e.getMessage());
        }
        return null;
    }

    /**
     * 生成一个自定义类名
     */
    public static String genClassName(){
        return "MemoryEntity".concat("$$").concat(String.valueOf(times.getAndAdd(1)));
    }


    public static void main(String[] args) {
        // 测试案例
        List<String> list = Arrays.asList("name", "age", "address");
        Object entity = memoryGenEntity(list, genClassName());
        System.out.println(entity);
        String name = entity.getClass().getName();
        System.out.println(name);
    }


}
